Refactor vector register moves. Eliminates code duplication, and moves between identical S registers are elided. Change-Id: Iec5d626c72f3c521a199a755e8804e26a5b4a782 Reviewed-on: https://chromium-review.googlesource.com/697946 Reviewed-by: Jim Stichnoth <stichnot@chromium.org> 
diff --git a/src/IceAssemblerARM32.cpp b/src/IceAssemblerARM32.cpp index 4b1fcb9..6f96985 100644 --- a/src/IceAssemblerARM32.cpp +++ b/src/IceAssemblerARM32.cpp 
@@ -1114,6 +1114,19 @@  emitInst(Encoding);  }   +void AssemblerARM32::emitMoveDD(IValueT Dd, IValueT Dm) { + // VMOV (register) - ARMv7-A/R section A8.6.327, encoding A1: + // VMOV<c> <Dd>, <Dm> + // + // 111100100D10mmmmdddd0001MQM1mmmm + constexpr IValueT VmovOpcode = B25 | B21 | B8 | B4; + constexpr bool UseQRegs = false; + constexpr bool IsFloatTy = false; + + if (Dd != Dm) + emitSIMDBase(VmovOpcode, Dd, Dm, Dm, UseQRegs, IsFloatTy); +} +  void AssemblerARM32::emitMoveSS(CondARM32::Cond Cond, IValueT Sd, IValueT Sm) {  // VMOV (register) - ARM section A8.8.340, encoding A2:  // vmov<c>.f32 <Sd>, <Sm> @@ -1121,7 +1134,9 @@  // cccc11101D110000dddd101001M0mmmm where cccc=Cond, ddddD=Sd, and mmmmM=Sm.  constexpr IValueT VmovssOpcode = B23 | B21 | B20 | B6;  constexpr IValueT S0 = 0; - emitVFPsss(Cond, VmovssOpcode, Sd, S0, Sm); + + if (Sd != Sm) + emitVFPsss(Cond, VmovssOpcode, Sd, S0, Sm);  }    void AssemblerARM32::emitMulOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, @@ -3479,20 +3494,14 @@  const IValueT Dn = mapQRegToDReg(encodeQRegister(OpQn, "Qn", Vzip));  const IValueT Dm = mapQRegToDReg(encodeQRegister(OpQm, "Qm", Vzip));   - constexpr bool UseQRegs = false; - constexpr bool IsFloatTy = false; - - // VMOV Dd, Dm - // 111100100D10mmmmdddd0001MQM1mmmm - constexpr IValueT VmovOpcode = B25 | B21 | B8 | B4; -  // Copy lower half of second source to upper half of destination. - emitSIMDBase(VmovOpcode, Dd + 1, Dm, Dm, UseQRegs, IsFloatTy); + emitMoveDD(Dd + 1, Dm);    // Copy lower half of first source to lower half of destination. - if (Dd != Dn) - emitSIMDBase(VmovOpcode, Dd, Dn, Dn, UseQRegs, IsFloatTy); + emitMoveDD(Dd, Dn);   + constexpr bool UseQRegs = false; + constexpr bool IsFloatTy = false;  constexpr IValueT ElmtShift = 18;  const IValueT ElmtSize = encodeElmtType(ElmtTy);  assert(Utils::IsUint(2, ElmtSize)); @@ -3554,15 +3563,8 @@  const IValueT Dn = mapQRegToDReg(encodeQRegister(OpQn, "Qn", Vmov));  const IValueT Dm = mapQRegToDReg(encodeQRegister(OpQm, "Qm", Vmov));   - constexpr bool UseQRegs = false; - constexpr bool IsFloat = false; - - const IValueT VmovOpcode = B25 | B21 | B8 | B4; - - if (Dd != Dm) - emitSIMDBase(VmovOpcode, Dd, Dm, Dm, UseQRegs, IsFloat); - if (Dd + 1 != Dn + 1) - emitSIMDBase(VmovOpcode, Dd + 1, Dn + 1, Dn + 1, UseQRegs, IsFloat); + emitMoveDD(Dd, Dm); + emitMoveDD(Dd + 1, Dn + 1);  }    void AssemblerARM32::vmovhq(const Operand *OpQd, const Operand *OpQn, @@ -3580,15 +3582,8 @@  const IValueT Dn = mapQRegToDReg(encodeQRegister(OpQn, "Qn", Vmov));  const IValueT Dm = mapQRegToDReg(encodeQRegister(OpQm, "Qm", Vmov));   - constexpr bool UseQRegs = false; - constexpr bool IsFloat = false; - - const IValueT VmovOpcode = B25 | B21 | B8 | B4; - - if (Dd != Dn) - emitSIMDBase(VmovOpcode, Dd, Dn, Dn, UseQRegs, IsFloat); - if (Dd + 1 != Dm + 1) - emitSIMDBase(VmovOpcode, Dd + 1, Dm + 1, Dm + 1, UseQRegs, IsFloat); + emitMoveDD(Dd, Dn); + emitMoveDD(Dd + 1, Dm + 1);  }    void AssemblerARM32::vmovhlq(const Operand *OpQd, const Operand *OpQn, @@ -3606,15 +3601,8 @@  const IValueT Dn = mapQRegToDReg(encodeQRegister(OpQn, "Qn", Vmov));  const IValueT Dm = mapQRegToDReg(encodeQRegister(OpQm, "Qm", Vmov));   - constexpr bool UseQRegs = false; - constexpr bool IsFloat = false; - - const IValueT VmovOpcode = B25 | B21 | B8 | B4; - - if (Dd != Dm + 1) - emitSIMDBase(VmovOpcode, Dd, Dm + 1, Dm + 1, UseQRegs, IsFloat); - if (Dd + 1 != Dn + 1) - emitSIMDBase(VmovOpcode, Dd + 1, Dn + 1, Dn + 1, UseQRegs, IsFloat); + emitMoveDD(Dd, Dm + 1); + emitMoveDD(Dd + 1, Dn + 1);  }    void AssemblerARM32::vmovlhq(const Operand *OpQd, const Operand *OpQn, @@ -3632,15 +3620,8 @@  const IValueT Dn = mapQRegToDReg(encodeQRegister(OpQn, "Qn", Vmov));  const IValueT Dm = mapQRegToDReg(encodeQRegister(OpQm, "Qm", Vmov));   - constexpr bool UseQRegs = false; - constexpr bool IsFloat = false; - - const IValueT VmovOpcode = B25 | B21 | B8 | B4; - - if (Dd + 1 != Dm) - emitSIMDBase(VmovOpcode, Dd + 1, Dm, Dm, UseQRegs, IsFloat); - if (Dd != Dn) - emitSIMDBase(VmovOpcode, Dd, Dn, Dn, UseQRegs, IsFloat); + emitMoveDD(Dd + 1, Dm); + emitMoveDD(Dd, Dn);  }    void AssemblerARM32::vnegqs(Type ElmtTy, const Operand *OpQd, @@ -3938,12 +3919,8 @@  } else {  // Narrow first source operand to lower half of destination.  emitSIMDBase(VqmovnOpcode, Dd, 0, Dm, UseQRegs, IsFloatTy); - - // VMOV Dd, Dm - // 111100100D10mmmmdddd0001MQM1mmmm - const IValueT VmovOpcode = B25 | B21 | B8 | B4; - - emitSIMDBase(VmovOpcode, Dd + 1, Dd, Dd, UseQRegs, IsFloatTy); + // Duplicate to upper half. + emitMoveDD(Dd + 1, Dd);  }  }   
diff --git a/src/IceAssemblerARM32.h b/src/IceAssemblerARM32.h index 43c3f56..f6d2416 100644 --- a/src/IceAssemblerARM32.h +++ b/src/IceAssemblerARM32.h 
@@ -809,8 +809,12 @@  uint32_t Index, const Operand *OpRt, bool IsExtract,  const char *InstName);   + // 111100100D10mmmmdddd0001MQM1mmmm where Ddddd=Dd, and Mmmmm=Dm. + // Assigns register Dd the value of register Dm. + void emitMoveDD(IValueT Dd, IValueT Dm); +  // cccc11101D110000dddd101001M0mmmm where cccc=Cond, ddddD=Sd, and mmmmM=Sm. - // Assigns Sd the value of Sm. + // Assigns register Sd the value of register Sm.  void emitMoveSS(CondARM32::Cond Cond, IValueT Sd, IValueT Sm);    // Pattern ccccxxxxxxxfnnnnddddssss1001mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,